// 购物车模块(只需要管理购物车列表数据)
import { getStockAPI, uploadMergeCartListAPI, getAllCartListAPI, addCartAPI, delCartAPI, updateCartAPI, updateSelectedAllCartAPI } from '@/api'

// 购物车状态
export default {
  namespaced: true,
  state () {
    return {
      // 购物车列表
      list: []
    }
  },
  mutations: {
    // 加入购物车
    INSERT_CART (state, goods) {
      // 目标: 判断下购物车里是否有这件商品+规格id, 如果有则数量增加, 如果无则新增
      const targetGoods = state.list.find(obj => obj.skuId === goods.skuId)
      if (targetGoods) {
        // 找到了
        targetGoods.count += goods.count
      } else {
        // 没找到
        // 新的商品加入到数组头部
        state.list.unshift(goods)
      }
    },
    // 更新本地购物车里每个商品+规格对象属性值
    UPDATE_CART (state, newGoods) {
      // 用索引取出本地购物车数组里对应对象
      const targetObj = state.list[newGoods.index]
      for (const key in newGoods) {
        if (key !== 'index') {
          targetObj[key] = newGoods[key]
        }
      }
    },
    // (本地)删除单个商品
    DELETE_CART (state, goods) {
      // goods: 要删除的那件商品对象信息(20多key+value, skuId)
      const index = state.list.findIndex(obj => obj.skuId === goods.skuId)
      state.list.splice(index, 1)
    },
    // 把线上购物车列表直接"覆盖"到本地
    SAT_LIST (state, payload) {
      state.list = payload
    }
  },
  actions: {
    // 加入购物车
    async insertCartActions (store, goods) {
      // 新的知识点: 在一个模块里访问另外一个模块里的值
      // store.rootState -> 拿到根state对象, 再通过模块名访问别的模块内state变量
      const { token } = store.rootState.user.profile
      if (token) {
        // 已登录
        await addCartAPI({
          skuId: goods.skuId,
          count: goods.count
        })
        // 线上实现: 所有动作(增删改)先调用线上接口(维护线上用户的购物车列表数据)
        // 再改后一定要用await等待改了成功以后, 再从线上获取回来所有数据覆盖vuex里list
        store.dispatch('getAllCartListActions')
      } else {
        // 未登录
        store.commit('INSERT_CART', goods)
      }
    },
    // 获取-每个商品最新状态(库存)
    getStockActions (store) {
      const newArr = store.state.list.map(async goodsObj => {
        return getStockAPI(goodsObj.skuId)
      })
      // 根据本地数组里顺序发起, 并且按照顺序接收回最新状态结果
      Promise.all(newArr).then(res => {
        console.log(res)
        const resultArr = res.map(obj => obj.result) // 把result结果对象返回形成新数组
        resultArr.forEach((obj, index) => {
          store.commit('UPDATE_CART', {
            ...obj,
            index: index // 此商品对象信息对应本地数组里索引
          })
        })
      })
      // Promise.all([小Promise, 小Promise, 小Promise])合并成一个大的Promise对象
      // 大的Promise对象的结果就是[]里面每个元素就是小Promise成功的结果(按顺序的)
      // 必须所有小Promise对象都为成功状态, 大的Promise对象才为成功
    },
    // 删除单个商品
    async deleteActions (store, goods) {
      const { token } = store.rootState.user.profile
      if (token) {
        // 已登录
        await delCartAPI([goods.skuId])
        store.dispatch('getAllCartListActions')
      } else {
        // 未登录
        store.commit('DELETE_CART', goods)
      }
    },
    // 更新单个商品(属性值)
    async updateCartActions (store, goods) {
      // goods: { skuId, selected }
      const { token } = store.rootState.user.profile
      if (token) {
        // 已登录
        await updateCartAPI({
          skuId: goods.skuId,
          selected: goods.selected
        })
        store.dispatch('getAllCartListActions')
      } else {
        // 未登录
        goods.index = store.state.list.findIndex(obj => obj.skuId === goods.skuId)
        store.commit('UPDATE_CART', goods)
      }
    },
    // 全选->所有商品
    async checkAllCartActions (store, bool) {
      const { token } = store.rootState.user.profile
      if (token) {
        // validList->转换成只有skuId的数组
        const skuIdsArr = store.getters.validList.map(obj => obj.skuId)
        // 已登录
        await updateSelectedAllCartAPI({
          selected: bool,
          ids: skuIdsArr
        })
        store.dispatch('getAllCartListActions')
      } else {
        // 未登录
        store.getters.validList.forEach(obj => {
          const index = store.state.list.findIndex(item => item.skuId === obj.skuId)
          store.commit('UPDATE_CART', {
            index: index,
            selected: bool
          })
        })
      }
    },
    // 合并购物车数据到线上
    async uploadMergeCartListActions (store) {
      const newArr = store.state.list.map(obj => ({
        skuId: obj.skuId,
        selected: obj.selected,
        count: obj.count
      }))
      const res = await uploadMergeCartListAPI(newArr)
      return res
      // actions函数内始终都会返回一个Promise对象
      // 只要你不返回Promise.reject()这样的对象, 其他的例如直接return res也会当做成功状态Promise的结果返回
    },
    // 获取-线上合并后购物车列表
    async getAllCartListActions (store) {
      const res = await getAllCartListAPI()
      console.log(res)
      store.commit('SAT_LIST', res.result)
    }
  },
  // 你买的时候有货, 后来看购物车列表时可能就没货了
  getters: {
    // 筛选有效商品的数组
    validList (state) {
      // stock最新库存量, inventory浏览商品选择时判断库存量
      return state.list.filter(goodsObj => goodsObj.isEffective === true && goodsObj.stock > 0)
    },
    // 统计有效商品总件数
    validTotal (state, getters) {
      return getters.validList.reduce((sum, goodsObj) => {
        sum += goodsObj.count
        return sum
      }, 0)
    },
    // 统计有效商品总价
    validAmount (state, getters) {
      return getters.validList.reduce((sum, goodsObj) => {
        sum += goodsObj.count * goodsObj.nowPrice
        return sum
      }, 0)
    },
    // 全选状态
    isCheckAll (state, getters) {
      return getters.validList.every(obj => obj.selected === true)
    },
    // 统计选中商品件数
    isSelAmount (state, getters) {
      return getters.validList.reduce((sum, obj) => {
        if (obj.selected === true) {
          sum += obj.count
        }

        return sum
      }, 0)
    },
    // 统计选中商品总价
    isSelTotal (state, getters) {
      return getters.validList.reduce((sum, obj) => {
        if (obj.selected === true) {
          sum += obj.count * obj.nowPrice
        }
        return sum
      }, 0)
    }
  }
}
